package com.sinodata.bsm.cicp.collector.tomcat;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class JvmCollector extends Collector {
    private static Logger logger = Logger.getLogger(CacheCollector.class);

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        String port = this.getParamMap().get("Port");
        String[] attributeNames = new String[] { "VmName", "VmVersion", "StartTime", "Uptime" };
        String[] attributeNames1 = new String[] { "Name", "TotalCompilationTime" };
        Object attrValues[] = null;
        Object tmp[] = new Object[5];
        String result[] = new String[5];
        String jvmName = this.getParamMap().get("Name").trim();
        Object propertyValues[] = null;
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];

        JMXConnector connector = null;
        MBeanServerConnection connection = null;

        try {
            connector = JmxUtil.getConnection(ip, Integer.parseInt(port));
            connection = connector.getMBeanServerConnection();
            ObjectName Jvm = new ObjectName("java.lang:type=Runtime");
            attrValues = JmxUtil.getAttribute(connection, Jvm, attributeNames);
            //attrValues[2] = sdf.format(new Date(Long.parseLong(attrValues[2].toString())));
            if (attrValues[0].toString().equals(jvmName)) {
                System.arraycopy(attrValues, 1, tmp, 0, 3);
                ObjectName compilation = new ObjectName("java.lang:type=Compilation");
                propertyValues = JmxUtil.getAttribute(connection, compilation, attributeNames1);
                System.arraycopy(propertyValues, 0, tmp, 3, 2);
            }
        } catch (Exception e) {
            logger.error("when JvmCollector:" + e);
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        for (int i = 0; i < tmp.length; i++) {
            if (tmp[i] != null) {
                result[i] = tmp[i].toString();
                propValues[i] = ResPropertyValue.createPropValue(result[i], propMetas[i]);
            }
        }
        DecimalFormat df = new DecimalFormat("0.00");
        if (result[2] != null) {
            result[2] = df.format(Double.parseDouble(result[2]) / 1000 / 60);
            propValues[2] = ResPropertyValue.createPropValue(result[2], propMetas[2]);

        }
        if (result[4] != null) {
            result[4] = String.valueOf(Double.parseDouble(result[4]) / 1000);
            propValues[4] = ResPropertyValue.createPropValue(result[4], propMetas[4]);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            if (result[1] != null) {

                result[1] = sdf.format(new Date(Long.parseLong(result[1].toString())));
                propValues[1] = ResPropertyValue.createPropValue(result[1], propMetas[1]);
            }
        } catch (Exception e) {
            logger.error("error occur when call JvmCollector.collect()" + e);
            throw new CollectorException(e);
        }
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "Name", "Port" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "虚拟机版本", "启动时间", "运行时间", "编译器名称", "编译总时间" };
        return new String[] { "$1", "$2", "$3", "$4", "$5" };
    }
}
